<?php
/**
 * CourseModel.class.php
 * 课程模型
 *
 * @author  王中艺
 * @date    2016-11-09
 */

namespace Wechat\Model;

class CourseModel extends BaseModel {

    //重定义数据表明
    protected   $trueTableName = 't_course';

    /**
     * 获取课程列表
     * @param   int     $userId     用户ID
     * @param   int     $page 页码数
     * @param   int     $buyType   课程类型 1.现金购买     2.积分换购
     * @param   int     $cate   课程类型 1.必修课  2.选修课
     * @return array    课程列表
     */
    function getList($userId, $buyType, $cate, $page){
        $page   = $page ? $page : 1;
        $where  = 'a.status = 1';
        if(isset($buyType)){
            $where  .= ' and a.buy_type = '.$buyType;
            if($buyType == 1)
                $where  .= ' and a.price > 0';
        }
        if($cate)
            $where  .= ' and a.cate = '.$cate;

        //课程列表获取
        $courses     = $this->table('t_course a', null)
            ->join('left join t_teacher b on a.teacher_id = b.id')
            ->where($where)
            ->cache(true)
            ->order('price desc')
            ->page($page, C('PAGE_COUNT'))
            ->field('a.id, a.name, a.banner, a.price, a.score, a.buy_count, a.play_type, a.tag, 
                a.chapter, b.name teacher_name')
            ->select();
        
        foreach($courses as $course){
            $courseIds[]    = $course['id'];
        }
        $courseIds  = implode(',', $courseIds);

        if(!$courseIds) return array();
          
        //用户课程状态查询
        $userCStatus  = M('t_user_course', null)
            ->where('user_id = %d and course_id in (%s)', $userId, $courseIds)
            ->getField('course_id, status');
        
        foreach($courses as &$val){
            $val['buy_status']   = $userCStatus[$val['id']] ? $userCStatus[$val['id']] : 0;
            $val['banner']  = C('SERVER_CDN').$val['banner'];
            $val['buy_status']  = $val['buy_status'] ? $val['buy_status'] : 0;
            $val['teacher_name']    = $val['teacher_name'] ? $val['teacher_name'] : '无效教师';
            //免费体验处理
            if($val['price'] == 0 && !$val['buy_status'])
                $val['buy_status'] = 1001;

            switch($val['id']){
                case 25:$val['buy_count'] += 650;break;
                case 24:$val['buy_count'] += 590;break;
                case 20:$val['buy_count'] += 710;break;
                case 27:$val['buy_count'] += 500;break;
            }
        }
        return $courses;
    }

    /**
     * 免费课程列表(0元课程+免费试听)
     * @param   $page 页码数
     * @return  $array
     */
    function freeList($page){
        //体验课程获取
        // $list   = M('t_course_chapter a')
        //     ->join('left join t_course b on a.course_id = b.id')
        //     ->join('left join t_teacher c on b.teacher_id = c.id')
        //     ->where('a.is_try = 1 and a.status = 1 and b.status = 1 and b.buy_type = 1')
        //     ->page($page, C('PAGE_COUNT'))
        //     ->group('b.id')
        //     ->field('b.name, b.price, c.name teacher_name, b.chapter chapter_count, b.buy_count, 
        //         a.name free_chapter_name, b.tag, b.banner, b.id, b.play_type')
        //     ->cache(true)
        //     ->select();

        $list   = $this->table('t_course as a')
            ->join('left join t_course_chapter b on a.id = b.course_id')
            ->join('left join t_teacher c on a.teacher_id = c.id')
            ->where('a.status = 1 and a.buy_type = 1 and (a.price = 0 or (b.is_try= 1 and b.status = 1))')
            ->field('a.id, a.name, a.price, c.name teaher_name, a.chapter chapter_count, a.buy_count,
                b.id chapter_id, b.name free_chapter_name, a.tag, a.banner, a.play_type')
            ->order('a.price, a.id')
            ->page($page, C('PAGE_COUNT'))
            ->group('a.id')
            ->cache(true)
            ->select();

        foreach($list as &$val){
            $val['banner']   = C('SERVER_CDN').$val['banner'];
            switch($val['id']){
                case 25:$val['buy_count'] += 650;break;
                case 24:$val['buy_count'] += 590;break;
                case 20:$val['buy_count'] += 710;break;
                case 27:$val['buy_count'] += 500;break;
            }
        }

        return $list;
    }

    /**
     * 课程批量获取
     * @param   $courseIds 课程IDs
     * @param   $status 课程状态
     * @return  array($list)
     */
    function batchGetCourses($courseIds, $status = false, $buyType = false){
        $courseIds  = implode(',', $courseIds);
        $where  = 'id in ('.$courseIds.')';
        if(is_numeric($status))
            $where  .= ' and status = '.$status;
        if(is_numeric($buyType))
            $where  .= ' and buy_type = '.$buyType;

        $list   = $this->where($where)->select();
        return $list;
    }

    /**
     * 课程详情信息获取
     * @param   $courseId
     * @return  $info
     */
    function detail($courseId, $userId){
        $courseInfo     = $this->table('t_course a')
            ->join('left join t_teacher b on a.teacher_id = b.id')
            ->join('left join t_user_course c on a.id = c.course_id and c.user_id = '.$userId)
            ->where('a.id = %d', $courseId)
            ->field('a.id, a.name, a.banner, a.decipt, a.price, a.score, a.play_type, a.main_title, a.sub_title,
                b.name teacher_name, b.decipt teacher_decipt, c.status as buy_status, c.watch_score')
            ->find();

        $courseInfo['banner']   = C('SERVER_CDN').$courseInfo['banner'];
        $courseInfo['teacher_name'] = $courseInfo['teacher_name'] ? $courseInfo['teacher_name'] : '无效教师';
        $courseInfo['teacher_decipt']   = $courseInfo['teacher_decipt'] ? $courseInfo['teacher_decipt'] : '无效教师';
        $courseInfo['buy_status']   = $courseInfo['buy_status'] ? $courseInfo['buy_status'] : 0;
        $courseInfo['decipt']   = str_replace(array("\r\n", "\n"), "<br>", $courseInfo['decipt']);
        $courseInfo['teacher_decipt']   = str_replace(array("\r\n", "\n"), "<br>", $courseInfo['teacher_decipt']);
        
        //免费课程处理
        if($courseInfo['price'] == 0 && !$courseInfo['buy_status']){
            $courseInfo['buy_status']   = 1001;
        }

        //课程章节获取
        $courseInfo['chapters']     = M('t_course_chapter', null)
            ->where('course_id = %d', $courseId)
            ->cache(true)
            ->field('name, is_try')
            ->select();
        return $courseInfo;
    }

    /**
     * 课程章节信息获取
     * @param  numb $userId
     * @param  numb $courseId 课程ID
     * @return array          课程信息
     */
    function chapters($userId, $courseId){
        //判断用户是否购买该课程
        $userHas  = M('t_user_course', null)
            ->where('user_id = %d and course_id = %d and (status = 1 or status = 3)', $userId, $courseId)
            ->cache(true)
            ->find();
        
        //课程信息获取
        $courseInfo     = M('t_course', null)->where('id = %d and status != -1', $courseId)->cache(true)->find();

        $chapters   = M('t_course_chapter', null)
            ->where('course_id = %d and status != -1', $courseId)
            ->cache(true)
            ->order('id')
            ->select();
        if(!$chapters){
            $this->errMsg   = '该课程暂无可播放章节!';
            return false;
        }

        $index = 2;
        foreach($chapters as $key => &$chapter){
            //章节序号添加
            $chapter['number']   = $key;
            $chapter['index_text']   = '试听章节';
            if($chapter['is_try'] != 1){
                $chapter['index_text']   = '第'.$index.'讲';
                $index++;
            }

            //判断章节是否可播放
            if($userHas || $chapter['is_try'] || ($courseInfo['price'] == 0 && $courseInfo['buy_type'] ==1)){
                $chapter['can_listen']  = 1;
                $chapter['audio']   = C('SERVER_CDN').$chapter['audio'];
                $chapter['attach']  = json_decode($chapter['attach'], true);
                $chapter['imgs']    = json_decode($chapter['imgs'], true);
                foreach($chapter['imgs'] as $key=>&$img){
                    if(!$img)   unset($chapter['imgs'][$key]);
                    $img    = C('SERVER_CDN').$img['path'];
                }
            }else{
                $chapter['can_listen']  = 0;
            }
            
            $chapter['time_text']   = sprintf("%d分钟", round($chapter['time']/60), 0);
            $chapter['format_minute']   = sprintf('%\'02d:%\'02d', round($chapter['time']/60, 0), round($chapter['time']%60, 0));
        }

        return $chapters;
    }

    /**
     * 获取用户课程列表
     * @param   $userId
     * @param   $page
     * @param   $status     课程状态
     * @return  array   $courses
     */
    function getUserCourses($userId, $page = 1, $status = false){
        $where  = 'a.user_id = '.$userId;
        // if($status)
        //     $where  .=' and a.status = '.$status;
        // else
        //     $where  .=' and a.status != -1';

        if(is_array($status)){
            $where  .= ' and a.status in ('.implode(',', $status).')';
        }else if(is_numeric($status)){
            $where  .= ' and a.status = '.$status;
        }else{
            $where  .= ' and a.status != -1';
        }

        $courses    = M('t_user_course a', null)
            ->join('left join t_course b on a.course_id = b.id')
            ->join('left join t_teacher c on b.teacher_id = c.id')
            ->where($where)
            ->page($page, C('PAGE_COUNT'))
            ->field('b.id course_id, b.name name, b.banner banner, b.play_type, b.tag, b.buy_count, 
                b.buy_type, b.price, b.score, b.chapter, c.name teacher_name, a.status')
            ->cache(true)
            ->select();

        foreach($courses as &$val){
            $val['banner']    = C('SERVER_CDN').$val['banner'];
            switch($val['course_id']){
                case 25:$val['buy_count'] += 650;break;
                case 24:$val['buy_count'] += 590;break;
                case 20:$val['buy_count'] += 710;break;
                case 27:$val['buy_count'] += 500;break;
            }
        }
        return $courses;
    }

    /**
     * 现金购买课程
     * @param   $courseId       课程ID
     * @param   $userId         用户ID
     * @return  $moneyInfo      交易信息
     */
    function buyByMoney($courseId, $userId){
        //用户课程信息
        $userCInfo  = M('t_user_course', null)
            ->where('user_id = %d and course_id = %d', $userId, $courseId)
            ->find();

        if($userCInfo){
            $this->errMsg   = '该课程已购买!';
            return false;
        }

        // if($userCInfo['status'] == 2){
        //     //订单已存在，继续该订单
        //     $moneyId  = $userCInfo['pay_money_id'];
        //     if(!$moneyId){
        //         $this->errMsg   = '无效订单ID';
        //         return false;
        //     }
        //     $moneyInfo  = M('t_money', null)->where('id = %d', $moneyId)->find();

        //     //更新交易单号
        //     $moneyInfo['trade_no']  = date('YmdHis').rand(1000, 9999);
        //     M('t_money', null)->save($moneyInfo);
        //     return $moneyInfo;
        // }

        $courseInfo     = $this->where('id = %d', $courseId)->find();
        if(!$courseInfo){
            $this->errMsg   = '指定课程未找到!';
            return false;
        }
        if($courseInfo['status'] != 1){
            $this->errMsg   = '课程不属于上架状态!';
            return false;
        }
        if($courseInfo['buy_type'] != 1){
            $this->errMsg   = '购买类型错误!';
            return false;
        }

        $this->startTrans();
        $remark     = json_encode(array('goods_name' => $courseInfo['name'], 'action' => '购买'));
        $moneyInfo  = D('Money')->createPay($userId, 1, $courseId, $courseInfo['price'], $remark);
        if(!$moneyInfo){
            $this->errMsg   = '交易信息生成失败,请重试!';
            $this->rollback();
            return false;
        }
        // //购买信息写入
        // $userCInfo  = array(
        //     'user_id'   => $userId,
        //     'course_id' => $courseId,
        //     'pay_money_id'    => $moneyInfo['id'],
        //     'price'     => $courseInfo['price'],
        //     'score' => 0,
        //     'create_time'   => time(),
        //     'watch_score'   => 0,
        //     'status'    => 2
        // );
        // if(!M('t_user_course', null)->add($userCInfo)){
        //     $this->errMsg   = '用户课程信息写入失败!';
        //     $this->rollback();
        //     return false;
        // }
        $this->commit();

        return $moneyInfo;
    }

    /**
     * 积分购买课程
     * @param  numb $courseId 课程ID
     * @param  numb $userId   用户ID
     * @return boolean        购买结果
     */
    function buyByScore($courseId, $userId){
        $userCInfo     = M('t_user_course', null)
            ->where('user_id = %d and course_id = %d', $userId, $courseId)
            ->find();
        if($userCInfo){
            $this->errMsg   = '该课程已购买或订单已存在!';
            return false;
        }

        $courseInfo     = $this->where('id = %d', $courseId)->find();
        if(!$courseInfo){
            $this->errMsg   = '指定课程未找到!';
            return false;
        }
        if($courseInfo['status'] != 1){
            $this->errMsg   = '课程不属于上架状态';
            return false;
        }
        if($courseInfo['buy_type'] != 2){
            $this->errMsg   = '购买类型错误!';
            return false;
        }

        //积分购买
        $dScore     = D('Score');
        $scoreInfo    = $dScore->payScore($userId, 5, $courseId, $courseInfo['score'], $courseInfo['name']);
        if(!$scoreInfo){
            $this->errMsg   = $dScore->errMsg;
            return false;
        }
        $this->where('id = %d', $courseId)->setInc('buy_count', 1);

        //购买信息
        $userCInfo   = array(
            'user_id'   => $userId,
            'course_id' => $courseId,
            'pay_score_id'  => $scoreInfo['id'],
            'price' => 0,
            'score' => $courseInfo['score'],
            'create_time'   => time(),
            'watch_score'   => 0,
            'get_type'  => 5,
            'get_relate_id' => $scoreInfo['id'],
            'status'    => 1
        );

        if(!M('t_user_course', null)->add($userCInfo)){
            $this->errMsg('购买信息写入失败!');
            return false;
        }

        return true;
    }

    /**
     * 现金支付成功回调
     * @param   $payInfo  支付信息
     * @return  boolean
     */
    function paySuccess($moneyInfo){
        $courseInfo     = M('t_course', null)
            ->where('id = %d', $moneyInfo['goods_id'])
            ->cache(true)
            ->find();

        $userCInfo  = array(
            'user_id'   => $moneyInfo['user_id'],
            'course_id' => $courseInfo['id'],
            'price' => $courseInfo['price'],
            'create_time'   => time(),
            'get_type'  => $moneyInfo['amount'] == 0 ? 4 : 1,
            'pay_money_id'  => $moneyInfo['id'],
            'get_relate_id' => $moneyInfo['id'],
            'status'    => 1
        );

        $retA   = $this->where('id = %d', $courseInfo['id'])->setInc('buy_count', 1);
        $retB   = M('t_user_course')->add($userCInfo);

        //发送模板消息
        $userInfo   = D('User')->getUserInfo($moneyInfo['user_id']);
        $wxTempMsg  = \Wechat\Util\WxTempMsg::getInstance();
        $wxTempMsg->buyCourse($userInfo, $courseInfo, $moneyInfo);

        return true;

        // $payId  = $payInfo['id'];    
        // $data['status'] = 1;
        // $result     = M('t_user_course', null)
        //     ->where('pay_money_id = %d', $payId)
        //     ->save($data);

        // $courseId   = $payInfo['goods_id'];
        // $this->where('id = %d', $courseId)->setInc('buy_count', 1);

        // //发送模板消息
        // $userInfo   = D('User')->getUserInfo($payInfo['user_id']);
        // $courseInfo     = M('t_course', null)->where('id = %d', $payInfo['goods_id'])->find();
        // $wxTempMsg  = \Wechat\Util\WxTempMsg::getInstance();
        // $wxTempMsg->buyCourse($userInfo, $courseInfo, $payInfo);
        
        // return true;
    }

    /**
     * 添加观看记录
     * @param   $courseId 课程ID
     * @param   $chapterId 章节ID
     * @param   $userId 用户ID
     * @return  $boolean
     */
    function addWatchLog($courseId, $chapterId, $userId){
        //观看记录添加
        $watchInfo  = array(
            'course_id' => $courseId,
            'chapter_id'    => $chapterId,
            'user_id'   => $userId,
            'watch_time'    => time()
        );
        $watchId    = M('t_log_watch', null)->add($watchInfo);

        //检测用户是否毕业，并添加相应积分
        $userCInfo  = M('t_user_course a', null)
            ->join('left join t_course b on a.course_id = b.id')
            ->where('a.user_id = %d and a.course_id = %d', $userId, $courseId)
            ->field('a.id, a.watch_score, b.chapter chapter_count, b.name course_name')
            ->find();

        if(!$userCInfo) return true;
        if($userCInfo['watch_score'] == 1)  return true;

        $hasWatches   = M('t_log_watch')
            ->where('user_id = %d and course_id = %d', $userId, $courseId)
            ->group('chapter_id')
            ->field('user_id, course_id, chapter_id, max(watch_time) watch_time')
            ->select();

        //尚未毕业
        if(count($hasWatches) < $userCInfo['chapter_count'])
            return true;

        //毕业执行积分获取逻辑
        $this->startTrans();
        $score      = 30;
        $result     = D('Score')->addScore($userId, 4, $courseId, $score, $userCInfo['course_name'], true);
        if($result === false){
            $this->rollback();
            $this->errMsg   = D('Score')->errMsg;
            return false;
        }
        $userCInfo['watch_score']   = 1;
        if(!M('t_user_course', null)->save($userCInfo)){
            $this->rollback();
            $this->errMsg   = '用户课程观看信息更改失败(t_user_course)!';
            return false;
        }
        $this->commit();

        return true;
    }

    /**
     * 获取最近观看课程信息
     * @param   $userId 用户ID
     * @return  $courseInfo 课程信息
     */
    function getLastWatch($userId){
        $courseInfo     = M('t_log_watch a', null)
            ->join('left join t_course b on a.course_id = b.id')
            ->join('left join t_course_chapter c on a.chapter_id = c.id')
            ->where('a.user_id = %d and b.status = 1', $userId)
            ->order('a.id desc')
            ->cache(true)
            ->field('a.course_id, a.chapter_id, b.banner, b.name, b.play_type, c.name chapter_name')
            ->find();

        $courseInfo['banner']   = C('SERVER_CDN').$courseInfo['banner'];
        return $courseInfo;
    }
}
